When a software application such as a video game or the like is compiled, it is typically converted into virtual code, such as an intermediate emulated binary that provides a description of the application as well as instructions as to how the application is to run. A software emulator performs a binary translation of a software application's intermediate binary at some point before the application is executed. Binary translation refers to the process of converting the intermediate binary into a machine-executable binary that is specific to the type of processor that will execute the code. The executable binary is then ready to be executed by the processor for which it has been formatted.
One such binary translation method is referred to as “just-in-time” (“JIT”) binary translation, which, as the name suggests, is a binary translation of software code that occurs just before the code is to be executed. As a result, a particular intermediate binary may be used on a variety of processors and computing platforms, as the processor-specific changes that need to occur for the code to run successfully do not happen until just prior to execution. JIT translation also provides relatively quick load and boot times because binary translation does not occur during boot-up.
Unfortunately, JIT translation may adversely affect the execution of the code at runtime. For example, a typical gaming system may be able to perform JIT translation during runtime for most average-complexity graphics functions within the code without having adverse effects on the code's execution (i.e., without affecting graphics rendering). However, if a particularly complex graphics function is encountered—such as one involving a large segment of artificial intelligence (“AI”)—there may not be sufficient processor resources available to perform both the function translation and the code execution. A user may therefore notice a momentary pause in code execution as a visible “flicker” or “stutter” during playback. As programmers constantly strive for increased graphics realism, such delays are becoming more and more undesirable.
Another translation method involves the use of a software precompiler. A precompiler performs a binary translation of the entire static intermediate binary that represents a software application's code prior to execution. The translation typically occurs when the software is being loaded during a boot-up process (at “load time”). While the use of a precompiler provides for faster, interruption-free execution at runtime, the initial load time when the precompiler performs the binary translation is lengthened. Thus, a user may experience an unreasonably long system boot time and, as a result, precompilers are typically not used for large programs.
Another problem occurs at runtime in connection with executing relatively simple functions within a machine-executable binary. For example, many functions involve calls from the main body of the code to a subroutine. The call to the subroutine and the call return from the subroutine (referred to as “context switching”) require processing time. For most functions, the processing time required for the context switch is negligible when compared to the processing time required to execute the function itself. However, if the function is very small the processing time required for the context switch may become a sizable percentage of the overall execution time required for the function. As a result, the execution of such a function as a subroutine is less efficient than if the function was simply executed within the main body of the code. This inefficiency can adversely affect the performance of JIT translation as well as code execution because of the extra processing time that is taken up by the context switch. While executing such a function as a subroutine may be inefficient, such subroutines in general typically serve as a convenient tool for software developers. Thus, simply creating code that has all such functions located in the main body of the code is undesirable.
Accordingly, there is a need for a mechanism that overcomes the above shortcomings and drawbacks. The present invention satisfies this need.